package org.e_gold.service.impl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
import org.e_gold.dao.ContractDAO;
import org.e_gold.dao.EventDAO;
import org.e_gold.dto.Cookies;
import org.e_gold.model.Contract;
import org.e_gold.model.Event;
import org.e_gold.service.ContractService;
import org.e_gold.util.Bet365;
import org.e_gold.util.CalcUtil;
import org.e_gold.util.StringUtil;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class ContractServiceImpl extends _NavigatorService implements ContractService, Bet365 {

	private static final Logger logger = Logger.getLogger(ContractServiceImpl.class);
	@Autowired
	private EventDAO eventDAO;

	@Autowired
	private ContractDAO contractDAO;

	@Override
	// production - backup
	public List<Contract> exposeAllContract(List<Event> events, Map<String, String> headers, Cookies cookies) {

		List<Contract> allContracts = new ArrayList<Contract>();
		if (CollectionUtils.isNotEmpty(events)) {
			logger.info(":::::::::::::::::::::::::::");
			logger.info(":::::::::::::::::::::::::::");
			logger.info("::::::Start Contract:::::::");
			logger.info(":::::::::::::::::::::::::::");
			logger.info(":::::::::::::::::::::::::::");
			for (Event event : events) {
				logger.info("----------------------");
				logger.info("Begin expose contract - Event : " + event.getName());
				logger.info("----------------------");
				try {
					Document contractPage = redirectNavigator(event.getLocation());
					if (hasAllMarkets(contractPage)) {
						// get all markets link and update event DB
						Element eAllMarketsLink = contractPage.select(ALL_MARKETS_CLASS + " a").get(0);
						event.setLocation("../coupon/" + eAllMarketsLink.attr("href"));
						event.setLocationFull(BASE_SPORT + "coupon/" + eAllMarketsLink.attr("href"));
						eventDAO.update(event);
						contractPage = redirectNavigator(event.getLocation());
					}
					Elements eContract = contractPage.select("a[href^=/AddToBetslip.aspx]");
					Set<Contract> setContracts = new HashSet<Contract>();
					for (Element e : eContract) {
						try {
							// insert new or populate old contract
							String contractStr = e.text();
							String contractType = StringUtil.getContractType(contractStr);
							Contract c = contractDAO.findByEventIdAndContractType(event.getId(), contractType);
							if (c == null) {
								c = new Contract();
								contractDAO.insert(c);
							}
							c.setEvent(event);
							c.setRate(CalcUtil.getRate(contractStr));
							c.setContractType(contractType);
							c.setBetSlipUrl(e.attr("href"));
							setContracts.add(c);
							contractDAO.update(c);
							logger.info("Contract : " + event.getName() + " - " + event.getPlayTime() + ":00" + " [" + event.getTotalGoal() + " ] - " + c.getContractType() + " - " + c.getRate());
							allContracts.add(c);
						} catch (Exception e2) {
							logger.info("expose contract error : " + e.text());
						}
					}
					if (setContracts.size() > 0) {
						event.setContracts(setContracts);
					}
					// Thread.sleep(CalcUtil.randomTime(1, 5) * 100);
				} catch (Exception e) {
					logger.info("Expose event error : " + event.getName());
				}
				logger.info("----------------------");
				logger.info("End expose contract - Event : " + event.getName());
				logger.info("----------------------");
			}
			logger.info(":::::::::::::::::::::::::::");
			logger.info(":::::::::::::::::::::::::::");
			logger.info("::::::End Contract:::::::");
			logger.info(":: Total exposed contracts : " + allContracts.size() + "  ::");
			logger.info(":::::::::::::::::::::::::::");
		}
		return allContracts;
	}

	private boolean hasAllMarkets(Document contractPage) {

		try {
			return contractPage.select(ALL_MARKETS_CLASS).size() > 0;
		} catch (Exception e) {
			logger.error(e);
		}
		return false;
	}

	@Override
	public Contract getRunningContract() {

		return contractDAO.getRunningContract();
	}

	@Override
	public void updateFalseQualify() {

		contractDAO.updateFalseQualify();
	}

	@Override
	public void updateFalseQualifyContract(List<Contract> lstContract) {
		StringBuilder sb = new StringBuilder();
		for(Contract ct : lstContract){
			sb.append(",");
			sb.append(ct.getId());
		}
		String idList = sb.substring(1).toLowerCase();
		contractDAO.updateFalseQualifyContract(idList);
	}

}
